In computer programming, indentation style is a convention or style, governing the indentation of lines of source code. An indentation style generally specifies a consistent number of whitespace characters before each line of a block, so that the lines of code appear to be related, and dictates whether to use spaces or Tab character as the indentation character.
Structured languages, such as Python and occam, use indentation to determine the structure instead of using braces or keywords; this is termed the off-side rule. In such languages, indentation is meaningful to the language processor (such as compiler or interpreter). A programmer must conform to the language's indentation rules although may be free to choose indentation size.
This article focuses on curly-bracket languages (that delimit blocks with curly bracket) and in particular C-family languages, but a convention used for one language can be adapted to another language. For example, a language that uses BEGIN and END keywords instead of braces can be adapted by treating BEGIN the same as the open brace and so on.
Indentation style only applies to text-based languages. Visual programming languages have no indentation.
foo(); bar();} | Allman |
{ foo(); bar(); } | GNU |
{ foo(); bar(); } | Whitesmiths |
foo(); bar();} | K&R |
foo(); bar(); } | Ratliff |
bar();} | Horstmann |
bar(); } | Pico |
{ foo(); bar(); } | Lisp |
| APL |
Although The C Programming Language does not explicitly define this style, it follows it consistently. From the book:
The position of braces is less important, although people hold passionate beliefs. We have chosen one of several popular styles. Pick a style that suits you, then use it consistently.
In this style, a function has its opening and closing braces on their own lines and with the same indentation as the declaration, while the statements in the body of the function are indented an additional level. A multi-statement block inside a function, however, has its opening brace on the same line as its control clause while the closing brace remains on its own line unless followed by a keyword such as else or while.
Example code:
while (x == y) {
do_something();
do_something_else();
if (some_error)
fix_issue(); // single-statement block without braces
else
continue_as_usual();
}
final_thing();
}
if (x < 0) {
return true;
} else {
return false;
}
}
Although not required by languages such as C/C++, using braces for single-statement blocks ensures inserting a new statement does not result in control flow that disagrees with indenting, as seen for example in Apple's infamous goto fail bug.
Some sources disagree as to the meaning of One True Brace Style – it might have slight differences based on most prevalent style for given language, individual authors might declare vastly distinct style as OTBS according to their subjective preferences, while others note it as "hacker jargon" for K&R.
int result;
if (y < 0) {
result = 0;
} else {
result = 1;
while (y-- > 0)
result *= x;
}
return result;
}
Unlike the variants above, Stroustrup does not use a "cuddled else". Thus, Stroustrup would write
if (x < 0) {
puts("Negative");
negative(x);
}
else {
puts("Non-negative");
nonnegative(x);
}
Stroustrup extends K&R style for classes, writing them as follows:
class Vector {
public:
// construct a Vector
Vector(int s) :elem(new double[s]), sz(s) { }
// element access: subscripting
double& operator[](int i) { return elem[i]; }
int size() { return sz; }
private:
// pointer to the elements
double * elem;
// number of elements
int sz;
};
Stroustrup does not indent the labels and . Also, in this style, while the opening brace of a function starts on a new line, the opening brace of a class is on the same line as the class name.
Stroustrup allows writing short functions all on one line. Stroustrup style is a named indentation style available in the editor Emacs. Stroustrup encourages a K&R-derived style layout with C++ as stated in his modern C++ Core Guidelines.
The SunOS kernel and userland uses a similar indentation style. Like KNF, this also was based on AT&T style documents and is sometimes termed Bill Joy Normal Form. The SunOS guideline was published in 1996; ANSI C is discussed briefly. The correctness of the indentation of a list of source files can be verified by the cstyle program written by Bill Shannon.
In this style, the hard tabulator (ts in vi) is kept at eight columns, while a soft tabulator is often defined as a helper also (sw in vi), and set at four. The hard tabulators are used to indent code blocks, while a soft tabulator (four spaces) of additional indentation is used for all continuing lines that must be split over multiple lines.
Moreover, function calls do not use a space before the parenthesis, although C-language native statements such as if, while, do, switch and return do (in the case where return is used with parens). Functions that declare no local variables in their top-level block should also leave an empty line after their opening block brace.
Examples:
something();
something_else();
}
final_thing();
if (JS_DefineProperty(cx, o, "data",
STRING_TO_JSVAL(JS_NewStringCopyN(cx, data, res)),
NULL, NULL, JSPROP_ENUMERATE) != 0) {
QUEUE_EXCEPTION("Internal error!");
goto err;
}
PQfreemem(data);
} else {
if (JS_DefineProperty(cx, o, "data", OBJECT_TO_JSVAL(NULL),
NULL, NULL, JSPROP_ENUMERATE) != 0) {
QUEUE_EXCEPTION("Internal error!");
goto err;
}
}
jsval *argv, jsval *rval)
{
QUEUE_EXCEPTION("PGresult class not user-instantiable");
return (JS_FALSE);
}
This style puts the brace associated with a control statement on the next line, indented to the same level as the control statement. Statements within the braces are indented to the next level.
final_thing();
something();
something_else();
}
This style is similar to the standard indentation used by the Pascal languages and Transact-SQL, where the braces are equivalent to the keywords begin and end.
while x = y do
begin
something();
something_else();
end;
end;
Consequences of this style are that the indented code is clearly set apart from the containing statement by lines that are almost all whitespace and the closing brace lines up in the same column as the opening brace. Some people feel this makes it easy to find matching braces. The blocking style also delineates the block of code from the associated control statement. Commenting out or removing a control statement or block of code, or code refactoring, are all less likely to introduce syntax errors via dangling or missing braces. Also, it is consistent with brace placement for the outer-function block.
For example, the following is still correct syntactically:
something();
something_else();
}
something();
something_else();
}
Even like this, with conditional compilation:
int c;
while ((c = getch()) != EOF)
while ((c = getchar()) != EOF)
{
do_something(c);
}
Whitesmiths, along with Allman, were claimed to have been the most common bracing styles in 1991 by the Jargon File, with roughly equal popularity at the time.
This style puts the brace associated with a control statement on the next line, indented. Statements within the braces are indented to the same level as the braces.
Like Ratliff style, the closing brace is indented the same as statements within the braces.
final_thing();
The advantages of this style are similar to those of the Allman style. Blocks are clearly set apart from control statements. The alignment of the braces with the block emphasizes that the full block is conceptually, and programmatically, one compound statement. Indenting the braces emphasizes that they are subordinate to the control statement. The ending brace no longer lines up with the statement, but instead with the opening brace.
An example:
else if are treated as statement, much like the #elif preprocessor statement.
Popularised by Richard Stallman, the layout may be influenced by his background of writing Lisp code. In Lisp, the equivalent to a block (a progn) is a first-class data entity, and giving it its own indentation level helps to emphasize that, whereas in C, a block is only syntax. This style can also be found in some ALGOL and XPL programming language textbooks from the 1960s and 1970s.W. M. McKeeman, J. J. Horning, and D. B. Wortman, A Compiler Generator
Although not indentation per se, GNU coding style also includes a space after a function name before the left parenthesis of an argument list.
This style combines the advantages of Allman and Whitesmiths, thereby removing the possible Whitesmiths disadvantage of braces not standing out from the block. One disadvantage is that the ending brace no longer lines up with the statement it conceptually belongs to. Another possible disadvantage is that it might waste space by using two visual levels of indents for one conceptual level, but in reality this is unlikely because, in systems with single-level indentation, each level is usually at least 4 spaces, same as 2 * 2 spaces in GNU style.
The GNU Coding Standards recommend this style, and nearly all maintainers of GNU project software use it.
The GNU Emacs text editor and the GNU systems' indent command will reformat code according to this style by default.Tested on the sample source code above on Ubuntu 18.04 with GNU indent 2.2.11 and GNU Emacs 25.2.2 started with emacs --no-init-file. Those who do not use GNU Emacs, or similarly extensible/customisable editors, may find that the automatic indentation settings of their editor are unhelpful for this style. However, many editors defaulting to KNF style cope well with the GNU style when the tab width is set to two spaces; likewise, GNU Emacs adapts well to KNF style by simply setting the tab width to eight spaces. In both cases, automatic reformatting destroys the original spacing, but automatic line indenting will work properly.
Steve McConnell, in his book Code Complete, advises against using this style: he marks a code sample which uses it with a "Coding Horror" icon, symbolizing especially dangerous code, and states that it impedes readability. The Linux kernel coding style documentation also recommends against this style, urging readers to burn a copy of the GNU coding standards as a "great symbolic gesture".
This style combines the advantages of Allman by keeping the vertical alignment of the braces for readability, and identifying blocks easily, with the saving of a line of the K&R style. However, the 2003 edition now uses Allman style throughout. Horstmann Style Guide
The advantages and disadvantages are similar to those of saving screen real estate with K&R style. An added advantage is that the starting and closing braces are consistent in application (both share space with a line of code), relative to K&R style, where one brace shares space with a line of code and one brace has a line alone.
The traditional Lisp variant of this style prefers extremely narrow levels of indentation (typically two spaces) because Lisp code usually nests very deeply since Lisp features only expressions, with no distinct class of statements; function arguments are mostly indented to the same level to illustrate their shared status within the enclosing expression. This is also because, braces aside, Lisp is conventionally a very terse language, omitting even common forms of simple boilerplate code as uninformative, such as the else keyword in an if : then | else block, instead rendering it uniformly as (if expr1 expr2 expr3).
braceful = do
In Haskell, layout can replace braces.
Usually the braces and semicolons are omitted for procedural do sections and the program text in general, but the style is commonly used for lists, records and other syntactic elements made up of some pair of parentheses or braces, which are separated with commas or semicolons. If code following the keywords where, let, or of omits braces and semicolons, then indentation is significant.Haskell Report 1.2 (1992), p.131 B.4 "Layout"
In addition to APL style C indentation, typically the names are shortened to either single or double characters: To reduce the amount of indentation, and expressions spanning multiple lines.
An experiment performed on PASCAL code in 1983, found that indentation size significantly affected comprehensibility. Indentation sizes between 2 and 4 characters proved optimal.
Although they both affect the general layout of code, indentation size is independent of the indentation style discussed here.
Storing in code can cause visual misalignment when viewed in different contexts, which counters the value of the indentation style.
Programmers lack consensus on storing tab characters.
Proponents of storing tab characters cite ease of typing and smaller text files since a single tab character serves the purpose of multiple spaces. Opponents, such as Jamie Zawinski, state that using spaces instead increases cross-platform Porting.
Others, such as the writers of the WordPress coding standards, state the opposite: that hard tabs increase portability. A survey of the top 400,000 repositories on GitHub found that spaces are more common.
Many text editors, including Notepad++, TextEdit, Emacs, vi, and GNU nano, can be configured to either store tab characters when entered via the tab key or to convert them to spaces (based on the configured tab width) so that tab characters are not added to the file when the tab key is pressed. Some editors can convert tab to space characters and vice versa.
Some Terminal pager, such as less, can be configured for a tab width. Some tools such as expand/unexpand can convert on the fly via filters.
Emacs provides commands to modify indentation, including hitting Tab on a given line. M-x indent-region indents code.
Elastic tabstops is a tabulation style which requires support from the text editor, where entire blocks of text are kept automatically aligned when the length of one line in the block changes.
Long compound statements can be a code smell of over complexity which can be solved by refactoring.
Programmers who rely on counting the opening braces may have difficulty with indentation styles such as K&R, where the starting brace is not visually separated from its Control flow. Programmers who rely more on indentations will gain more from styles that are vertically compact, such as K&R, because the blocks are shorter.
To avoid losing track of control statements such as [[for|for loop]], a large indentation can be used, such as an 8-unit-wide hard tab, along with breaking up large functions into smaller and more readable functions. Linux is done this way, while using the K&R style.
Some text editors allow the programmer to jump between the two corresponding braces of a block.
For example, vi jumps to the brace enclosing the same block as the one under the cursor when pressing the % key.
Since the text cursor's next key (viz., the n key) retained directional positioning information (whether the up or down key was formerly pressed), the dot macro (the . key) could then be used to place the text cursor on the next brace, given a suitable coding style. Instead, inspecting the block boundaries using the % key can be used to enforce a coding standard.
Another way to maintain block awareness, is to use comments after the closing brace. For example:
A disadvantage is maintaining the same code in multiple locations above and below the block.
Some editors provide support for maintaining block awareness. A folding editor can hide (fold) and reveal (unfold) blocks by indentation level. Some editors highlight matching braces when the cursor is positioned next to one.
{
something();
something_else();
}
{
if (!JS_DefineProperty(cx, o, "data", STRING_TO_JSVAL(JS_NewStringCopyN(cx, data, res)), NULL, NULL, JSPROP_ENUMERATE))
{
QUEUE_EXCEPTION("Internal error!");
goto err;
}
PQfreemem(data);
}
else if (!JS_DefineProperty(cx, o, "data", OBJECT_TO_JSVAL(NULL), NULL, NULL, JSPROP_ENUMERATE))
{
QUEUE_EXCEPTION("Internal error!");
goto err;
}
GNU
/ref>
while (x == y)
{
something ();
something_else ();
}
final_thing ();
}
Horstmann
something_else();
//...
if (x < 0)
{ printf("Negative");
negative(x);
}
else
{ printf("Non-negative");
nonnegative(x);
}
}
final_thing();
Pico
stuff(n):
{ x: 3 * n;
y: do_stuff(x);
y + x }
Ratliff
// In C
for (i = 0; i < 10; i++) {
if (i % 2 == 0) {
do_something(i);
}
else {
do_something_else(i);
}
}
C derived language styles
Lisp style
{if (i % 2 == 0)
{do_something(i);}
else
{do_something_else(i);
do_third_thing(i);}}
(dotimes (i 10)
(if (= (rem i 2) 0)
(do-something i)
(progn
(do-something-else i)
(do-third-thing i))))
Haskell style
text <- getContents
let
firstWord = head $ words text
bigWord = map toUpper firstWord
putStrLn bigWord
{ text <- getContents
; let
{ firstWord = head $ words text
; bigWord = map toUpper firstWord
}
; putStrLn bigWord
}
APL style
Indentation size
Tab vs. space
Style automation
Losing track of blocks
foo();
} //for (i)
bar();
} //if (x < 0)
See also
External links
Tabs and spaces
|
|